package distrcomp;

import java.io.InputStream;
import java.io.StringWriter;
import java.rmi.NotBoundException;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.HashMap;

import javax.rmi.ssl.SslRMIClientSocketFactory;

/*
 * Server class
 */

public class Server {
	private ShippingQuoterImpl s;
	private RegisterSubserverImpl r;
	private AdminImpl a;
	private HashMap<ShippingType, Float> prices;
	private String registry;
	
	public Server(String registry) throws RemoteException {
		this.s = new ShippingQuoterImpl();
		this.r = new RegisterSubserverImpl(this);
		this.a = new AdminImpl(this);
		this.prices = new HashMap<ShippingType, Float>();
		this.prices.put(ShippingType.GROUND, (float) 5.95);
		this.prices.put(ShippingType.AIR, (float) 8.95);
		this.prices.put(ShippingType.AIR_PRIORITY, (float) 12.95);
		this.registry = registry;
	}
	
	public void run() throws RemoteException {
		//Register the service with the registry running on another machine
		try {
			Registry registry = LocateRegistry.getRegistry(this.registry, 1099, new SslRMIClientSocketFactory());
			MyRegistry reg = (MyRegistry) registry.lookup("Registry");
	
		
			if(reg.bind("ShippingService", s)) {
				System.out.println("Binded ShippingService succesfully with external registry.");
			}
			if(reg.bind("RegisterService", r)) {
				System.out.println("Binded RegisterService succesfully with external registry.");
			}
			if(reg.bind("AdminService", a)) {
				System.out.println("Binded AdminService succesfully with external registry.");
			}
		} catch (NotBoundException e) {
			e.printStackTrace();
		}
	}
	
	public HashMap<Integer, Subserver> getSubservers() {
		return s.getSubservers();
	}
	
	public int addSubserver(Subserver subserver) {
		return this.s.addSubserver(subserver);
	}
	
	public void addSubserver(Subserver subserver, int ID) {
		this.s.addSubserver(subserver, ID);
	}
	
	public int getHighestShipmentID() {
		return s.getHighestShipmentID();
	}
	
	public Subserver getServer(int shipmentKey) {
		return s.getServer(shipmentKey);
	}
	
	public void setRate(ShippingType type, float rate) {
		this.prices.put(type, rate);
	}
	
	public void setRates(float ground, float air, float air_pr) {
		this.prices.put(ShippingType.GROUND, ground);
		this.prices.put(ShippingType.AIR, air);
		this.prices.put(ShippingType.AIR_PRIORITY, air_pr);
	}
	
	public float getRate(ShippingType type) {
		return this.prices.get(type);
	}
}
